home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Source / GNU / cc / math-68881.h < prev    next >
C/C++ Source or Header  |  1993-09-28  |  10KB  |  527 lines

  1. /******************************************************************\
  2. *                                   *
  3. *  <math-68881.h>        last modified: 23 May 1992.       *
  4. *                                   *
  5. *  Copyright (C) 1989 by Matthew Self.                   *
  6. *  You may freely distribute verbatim copies of this software       *
  7. *  provided that this copyright notice is retained in all copies.  *
  8. *  You may distribute modifications to this software under the     *
  9. *  conditions above if you also clearly note such modifications    *
  10. *  with their author and date.                               *
  11. *                                   *
  12. *  Note:  errno is not set to EDOM when domain errors occur for    *
  13. *  most of these functions.  Rather, it is assumed that the       *
  14. *  68881's OPERR exception will be enabled and handled           *
  15. *  appropriately by the    operating system.  Similarly, overflow       *
  16. *  and underflow do not set errno to ERANGE.               *
  17. *                                   *
  18. *  Send bugs to Matthew Self (self@bayes.arc.nasa.gov).           *
  19. *                                   *
  20. \******************************************************************/
  21.  
  22. /* This file is NOT a part of GCC, just distributed with it.  */
  23.  
  24. /* If you find this in GCC,
  25.    please send bug reports to bug-gcc@prep.ai.mit.edu.  */
  26.  
  27. /* Changed by Richard Stallman:
  28.    May 1993, add conditional to prevent multiple inclusion.
  29.    % inserted before a #.
  30.    New function `hypot' added.
  31.    Nans written in hex to avoid 0rnan.
  32.    May 1992, use %! for fpcr register.  Break lines before function names.
  33.    December 1989, add parens around `&' in pow.
  34.    November 1990, added alternate definition of HUGE_VAL for Sun.  */
  35.  
  36. /* Changed by Jim Wilson:
  37.    September 1993, Use #undef before HUGE_VAL instead of #ifdef/#endif.  */
  38.  
  39. #ifndef __math_68881
  40. #define __math_68881
  41.  
  42. #include <errno.h>
  43.  
  44. #undef HUGE_VAL
  45. #ifdef __sun__
  46. /* The Sun assembler fails to handle the hex constant in the usual defn.  */
  47. #define HUGE_VAL                            \
  48. ({                                    \
  49.   static union { int i[2]; double d; } u = { {0x7ff00000, 0} };        \
  50.   u.d;                                    \
  51. })
  52. #else
  53. #define HUGE_VAL                            \
  54. ({                                    \
  55.   double huge_val;                            \
  56.                                     \
  57.   __asm ("fmove%.d %#0x7ff0000000000000,%0"    /* Infinity */        \
  58.      : "=f" (huge_val)                        \
  59.      : /* no inputs */);                        \
  60.   huge_val;                                \
  61. })
  62. #endif
  63.  
  64. __inline static const double
  65. sin (double x)
  66. {
  67.   double value;
  68.  
  69.   __asm ("fsin%.x %1,%0"
  70.      : "=f" (value)
  71.      : "f" (x));
  72.   return value;
  73. }
  74.  
  75. __inline static const double
  76. cos (double x)
  77. {
  78.   double value;
  79.  
  80.   __asm ("fcos%.x %1,%0"
  81.      : "=f" (value)
  82.      : "f" (x));
  83.   return value;
  84. }
  85.  
  86. __inline static const double
  87. tan (double x)
  88. {
  89.   double value;
  90.  
  91.   __asm ("ftan%.x %1,%0"
  92.      : "=f" (value)
  93.      : "f" (x));
  94.   return value;
  95. }
  96.  
  97. __inline static const double
  98. asin (double x)
  99. {
  100.   double value;
  101.  
  102.   __asm ("fasin%.x %1,%0"
  103.      : "=f" (value)
  104.      : "f" (x));
  105.   return value;
  106. }
  107.  
  108. __inline static const double
  109. acos (double x)
  110. {
  111.   double value;
  112.  
  113.   __asm ("facos%.x %1,%0"
  114.      : "=f" (value)
  115.      : "f" (x));
  116.   return value;
  117. }
  118.  
  119. __inline static const double
  120. atan (double x)
  121. {
  122.   double value;
  123.  
  124.   __asm ("fatan%.x %1,%0"
  125.      : "=f" (value)
  126.      : "f" (x));
  127.   return value;
  128. }
  129.  
  130. __inline static const double
  131. atan2 (double y, double x)
  132. {
  133.   double pi, pi_over_2;
  134.  
  135.   __asm ("fmovecr%.x %#0,%0"        /* extended precision pi */
  136.      : "=f" (pi)
  137.      : /* no inputs */ );
  138.   __asm ("fscale%.b %#-1,%0"        /* no loss of accuracy */
  139.      : "=f" (pi_over_2)
  140.      : "0" (pi));
  141.   if (x > 0)
  142.     {
  143.       if (y > 0)
  144.     {
  145.       if (x > y)
  146.         return atan (y / x);
  147.       else
  148.         return pi_over_2 - atan (x / y);
  149.     }
  150.       else
  151.     {
  152.       if (x > -y)
  153.         return atan (y / x);
  154.       else
  155.         return - pi_over_2 - atan (x / y);
  156.     }
  157.     }
  158.   else
  159.     {
  160.       if (y < 0)
  161.     {
  162.       if (-x > -y)
  163.         return - pi + atan (y / x);
  164.       else
  165.         return - pi_over_2 - atan (x / y);
  166.     }
  167.       else
  168.     {
  169.       if (-x > y)
  170.         return pi + atan (y / x);
  171.       else if (y > 0)
  172.         return pi_over_2 - atan (x / y);
  173.       else
  174.         {
  175.           double value;
  176.  
  177.           errno = EDOM;
  178.           __asm ("fmove%.d %#0x7fffffffffffffff,%0"     /* quiet NaN */
  179.              : "=f" (value)
  180.              : /* no inputs */);
  181.           return value;
  182.         }
  183.     }
  184.     }
  185. }
  186.  
  187. __inline static const double
  188. sinh (double x)
  189. {
  190.   double value;
  191.  
  192.   __asm ("fsinh%.x %1,%0"
  193.      : "=f" (value)
  194.      : "f" (x));
  195.   return value;
  196. }
  197.  
  198. __inline static const double
  199. cosh (double x)
  200. {
  201.   double value;
  202.  
  203.   __asm ("fcosh%.x %1,%0"
  204.      : "=f" (value)
  205.      : "f" (x));
  206.   return value;
  207. }
  208.  
  209. __inline static const double
  210. tanh (double x)
  211. {
  212.   double value;
  213.  
  214.   __asm ("ftanh%.x %1,%0"
  215.      : "=f" (value)
  216.      : "f" (x));
  217.   return value;
  218. }
  219.  
  220. __inline static const double
  221. atanh (double x)
  222. {
  223.   double value;
  224.  
  225.   __asm ("fatanh%.x %1,%0"
  226.      : "=f" (value)
  227.      : "f" (x));
  228.   return value;
  229. }
  230.  
  231. __inline static const double
  232. exp (double x)
  233. {
  234.   double value;
  235.  
  236.   __asm ("fetox%.x %1,%0"
  237.      : "=f" (value)
  238.      : "f" (x));
  239.   return value;
  240. }
  241.  
  242. __inline static const double
  243. expm1 (double x)
  244. {
  245.   double value;
  246.  
  247.   __asm ("fetoxm1%.x %1,%0"
  248.      : "=f" (value)
  249.      : "f" (x));
  250.   return value;
  251. }
  252.  
  253. __inline static const double
  254. log (double x)
  255. {
  256.   double value;
  257.  
  258.   __asm ("flogn%.x %1,%0"
  259.      : "=f" (value)
  260.      : "f" (x));
  261.   return value;
  262. }
  263.  
  264. __inline static const double
  265. log1p (double x)
  266. {
  267.   double value;
  268.  
  269.   __asm ("flognp1%.x %1,%0"
  270.      : "=f" (value)
  271.      : "f" (x));
  272.   return value;
  273. }
  274.  
  275. __inline static const double
  276. log10 (double x)
  277. {
  278.   double value;
  279.  
  280.   __asm ("flog10%.x %1,%0"
  281.      : "=f" (value)
  282.      : "f" (x));
  283.   return value;
  284. }
  285.  
  286. __inline static const double
  287. sqrt (double x)
  288. {
  289.   double value;
  290.  
  291.   __asm ("fsqrt%.x %1,%0"
  292.      : "=f" (value)
  293.      : "f" (x));
  294.   return value;
  295. }
  296.  
  297. __inline static const double
  298. hypot (const double x, const double y)
  299. {
  300.   return sqrt (x*x + y*y);
  301. }
  302.  
  303. __inline static const double
  304. pow (const double x, const double y)
  305. {
  306.   if (x > 0)
  307.     return exp (y * log (x));
  308.   else if (x == 0)
  309.     {
  310.       if (y > 0)
  311.     return 0.0;
  312.       else
  313.     {
  314.       double value;
  315.  
  316.       errno = EDOM;
  317.       __asm ("fmove%.d %#0x7fffffffffffffff,%0"        /* quiet NaN */
  318.          : "=f" (value)
  319.          : /* no inputs */);
  320.       return value;
  321.     }
  322.     }
  323.   else
  324.     {
  325.       double temp;
  326.  
  327.       __asm ("fintrz%.x %1,%0"
  328.          : "=f" (temp)            /* integer-valued float */
  329.          : "f" (y));
  330.       if (y == temp)
  331.         {
  332.       int i = (int) y;
  333.       
  334.       if ((i & 1) == 0)            /* even */
  335.         return exp (y * log (-x));
  336.       else
  337.         return - exp (y * log (-x));
  338.         }
  339.       else
  340.         {
  341.       double value;
  342.  
  343.       errno = EDOM;
  344.       __asm ("fmove%.d %#0x7fffffffffffffff,%0"        /* quiet NaN */
  345.          : "=f" (value)
  346.          : /* no inputs */);
  347.       return value;
  348.         }
  349.     }
  350. }
  351.  
  352. __inline static const double
  353. fabs (double x)
  354. {
  355.   double value;
  356.  
  357.   __asm ("fabs%.x %1,%0"
  358.      : "=f" (value)
  359.      : "f" (x));
  360.   return value;
  361. }
  362.  
  363. __inline static const double
  364. ceil (double x)
  365. {
  366.   int rounding_mode, round_up;
  367.   double value;
  368.  
  369.   __asm volatile ("fmove%.l %!,%0"
  370.           : "=dm" (rounding_mode)
  371.           : /* no inputs */ );
  372.   round_up = rounding_mode | 0x30;
  373.   __asm volatile ("fmove%.l %0,%!"
  374.           : /* no outputs */
  375.           : "dmi" (round_up));
  376.   __asm volatile ("fint%.x %1,%0"
  377.           : "=f" (value)
  378.           : "f" (x));
  379.   __asm volatile ("fmove%.l %0,%!"
  380.           : /* no outputs */
  381.           : "dmi" (rounding_mode));
  382.   return value;
  383. }
  384.  
  385. __inline static const double
  386. floor (double x)
  387. {
  388.   int rounding_mode, round_down;
  389.   double value;
  390.  
  391.   __asm volatile ("fmove%.l %!,%0"
  392.           : "=dm" (rounding_mode)
  393.           : /* no inputs */ );
  394.   round_down = (rounding_mode & ~0x10)
  395.         | 0x20;
  396.   __asm volatile ("fmove%.l %0,%!"
  397.           : /* no outputs */
  398.           : "dmi" (round_down));
  399.   __asm volatile ("fint%.x %1,%0"
  400.           : "=f" (value)
  401.           : "f" (x));
  402.   __asm volatile ("fmove%.l %0,%!"
  403.           : /* no outputs */
  404.           : "dmi" (rounding_mode));
  405.   return value;
  406. }
  407.  
  408. __inline static const double
  409. rint (double x)
  410. {
  411.   int rounding_mode, round_nearest;
  412.   double value;
  413.  
  414.   __asm volatile ("fmove%.l %!,%0"
  415.           : "=dm" (rounding_mode)
  416.           : /* no inputs */ );
  417.   round_nearest = rounding_mode & ~0x30;
  418.   __asm volatile ("fmove%.l %0,%!"
  419.           : /* no outputs */
  420.           : "dmi" (round_nearest));
  421.   __asm volatile ("fint%.x %1,%0"
  422.           : "=f" (value)
  423.           : "f" (x));
  424.   __asm volatile ("fmove%.l %0,%!"
  425.           : /* no outputs */
  426.           : "dmi" (rounding_mode));
  427.   return value;
  428. }
  429.  
  430. __inline static const double
  431. fmod (double x, double y)
  432. {
  433.   double value;
  434.  
  435.   __asm ("fmod%.x %2,%0"
  436.      : "=f" (value)
  437.      : "0" (x),
  438.        "f" (y));
  439.   return value;
  440. }
  441.  
  442. __inline static const double
  443. drem (double x, double y)
  444. {
  445.   double value;
  446.  
  447.   __asm ("frem%.x %2,%0"
  448.      : "=f" (value)
  449.      : "0" (x),
  450.        "f" (y));
  451.   return value;
  452. }
  453.  
  454. __inline static const double
  455. scalb (double x, int n)
  456. {
  457.   double value;
  458.  
  459.   __asm ("fscale%.l %2,%0"
  460.      : "=f" (value)
  461.      : "0" (x),
  462.        "dmi" (n));
  463.   return value;
  464. }
  465.  
  466. __inline static double
  467. logb (double x)
  468. {
  469.   double exponent;
  470.  
  471.   __asm ("fgetexp%.x %1,%0"
  472.      : "=f" (exponent)
  473.      : "f" (x));
  474.   return exponent;
  475. }
  476.  
  477. __inline static const double
  478. ldexp (double x, int n)
  479. {
  480.   double value;
  481.  
  482.   __asm ("fscale%.l %2,%0"
  483.      : "=f" (value)
  484.      : "0" (x),
  485.        "dmi" (n));
  486.   return value;
  487. }
  488.  
  489. __inline static double
  490. frexp (double x, int *exp)
  491. {
  492.   double float_exponent;
  493.   int int_exponent;
  494.   double mantissa;
  495.  
  496.   __asm ("fgetexp%.x %1,%0"
  497.      : "=f" (float_exponent)     /* integer-valued float */
  498.      : "f" (x));
  499.   int_exponent = (int) float_exponent;
  500.   __asm ("fgetman%.x %1,%0"
  501.      : "=f" (mantissa)        /* 1.0 <= mantissa < 2.0 */
  502.      : "f" (x));
  503.   if (mantissa != 0)
  504.     {
  505.       __asm ("fscale%.b %#-1,%0"
  506.          : "=f" (mantissa)        /* mantissa /= 2.0 */
  507.          : "0" (mantissa));
  508.       int_exponent += 1;
  509.     }
  510.   *exp = int_exponent;
  511.   return mantissa;
  512. }
  513.  
  514. __inline static double
  515. modf (double x, double *ip)
  516. {
  517.   double temp;
  518.  
  519.   __asm ("fintrz%.x %1,%0"
  520.      : "=f" (temp)            /* integer-valued float */
  521.      : "f" (x));
  522.   *ip = temp;
  523.   return x - temp;
  524. }
  525.  
  526. #endif /* not __math_68881 */
  527.